﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.ComponentModel;

namespace TFDP.Common.Configuration
{
    public interface ISetting : INotifyPropertyChanged
    {
        string Key { get; set; }
        object Value { get; set; }
        Type ValueType { get; }
    }

    public class Setting<T> : ISetting
    {
        public string Key { get; set; }

        public T Value { get; set; }

        public Type ValueType { get { return typeof(T); } }

        public Setting()
        {
            Value = (T)Activator.CreateInstance(typeof(T));
        }

        #region ISetting Members

        object ISetting.Value
        {
            get
            {
                return Value;
            }
            set
            {
                this.Value = (T)value;
                RaisePropertyChanged("Value");
            }
        }

        #endregion

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    public class StringSetting : ISetting
    {
        private string key;
        private string value;
        private readonly static Type valueType = typeof(string);

        #region ISetting Members

        public string Key
        {
            get
            {
                return key;
            }
            set
            {
                if (!String.Equals(key, value, StringComparison.InvariantCultureIgnoreCase))
                {
                    key = value;
                    RaisePropertyChanged("Key");
                }
            }
        }

        public object Value
        {
            get
            {
                return value;
            }
            set
            {
                if (value == null || value.GetType() != typeof(string))
                {
                    this.value = null;
                }
                else if (!String.Equals(this.value, (string)value, StringComparison.InvariantCultureIgnoreCase))
                {
                    this.value = (string)value;
                    RaisePropertyChanged("Value");
                }
            }
        }

        public Type ValueType
        {
            get { return valueType; }
        }

        #endregion

        public event PropertyChangedEventHandler PropertyChanged;

        private void RaisePropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}
